//
// Created by 小演员的MacBook on 2024/7/23.
//

#include <iostream>

//函数模板；有自动推导和显示指定 两种方式；模板参数列表中的参数不能有默认参数类型；
template<typename T>//声明一个模板，告诉编译器后面代码中紧跟着的T不要报错，T是一个通用的数据类型
void swap(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
    std::cout << typeid(T).name() << std::endl;
}

template<class T>//声明一个模板，告诉编译器后面代码中紧跟着的T不要报错，T是一个通用的数据类型
void swap1(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

class Person {
    int age;
};

template<> void swap1<Person>(Person &a, Person &b) {
    std::cout << "Person swap" << std::endl;
}
template<> void swap(Person &a, Person &b) {
    std::cout << "Person swap" << std::endl;
}
//类模板；没有自动推导，只有显示指定；类模板在模板参数列表中可以有默认参数；
template<class T, class R = std::string>
class Student1 {
public:
    T age;
    R name;
    Student1(T age, R name) {
        this->age = age;
        this->name = name;
    }
};

int main() {
    //交换整型
    int a = 10;
    int b = 20;
    swap(a, b);
    std::cout << "a=" << a << ",b=" << b << std::endl;
    //交换浮点型
    float c = 10.1;
    float d = 20.1;
    swap(c, d);
    std::cout << "c=" << c << ",d=" << d << std::endl;
    //显示指定类型
    swap<int>(a, b);
    std::cout << "a=" << a << ",b=" << b << std::endl;

    swap1(a, b);
    std::cout << "a=" << a << ",b=" << b << std::endl;

    Student1<int, std::string> student1(10, "小明");//<int, std::string>传的是模板参数列表中参数类型；(10, "小明")传的是具体的参数值
    std::cout << "student1.age=" << student1.age << ",student1.name=" << student1.name << std::endl;
    Student1<int> student2(10, "小明");
    std::cout << "student2.age=" << student2.age << ",student2.name=" << student2.name << std::endl;

    return 0;
}
